/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gblend.adjlistgraph;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;

/**
 * An fsg id entry for large graph case, instead just an integer (ID) to indicate
 * a graph, this contain a list of ID of partitioned/border graph && a boolean to
 * indicate if the fragment lay at the boundary of the combined graph.
 * @author HO HOANG HUNG
 */
public class FsgIdEntry implements Comparable {

    private HashSet<Integer> graphIdSequence = new HashSet<Integer>(5);
    //   private boolean atBoundary = false;

    public FsgIdEntry(int firstgid) {
        graphIdSequence.add(firstgid);
    }

    public FsgIdEntry(HashSet<Integer> seq) {
        graphIdSequence = new HashSet<Integer>(seq);
    }

    public FsgIdEntry(FsgIdEntry e){
        graphIdSequence = new HashSet<Integer>(e.graphIdSequence);
    }

    public FsgIdEntry() {
    }

    public Vector<Integer> getGraphId() {
        Vector<Integer> gIdSeq = new Vector<Integer>(graphIdSequence);
        Collections.sort(gIdSeq);
        return gIdSeq;
    }

    /**
     * return the # of id in this entry
     */
    public int getIdSize() {
        return graphIdSequence.size();
    }

    /*public boolean isAtBoundary() {
    return atBoundary;
    }

    public void setAtBoundary(boolean ab) {
    atBoundary = ab;
    }*/
    public void addGraphId(int newId) {
        graphIdSequence.add(newId);
    }

    @Override
    public boolean equals(Object oth) {
        if (oth instanceof FsgIdEntry) {
            FsgIdEntry o = (FsgIdEntry) oth;
         //   System.out.print("I am "+this.toString()+" you re "+o.toString());
            if (graphIdSequence.equals(o.graphIdSequence)) {
          //      System.out.println(" equals");
                return true;
            } else {
           //     System.out.println(" not equals");
                return false;
            }
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 17 * hash + (this.graphIdSequence != null ? this.graphIdSequence.hashCode() : 0);
        return hash;
    }

    public int compareTo(Object o) {
        if (o instanceof FsgIdEntry) {
            FsgIdEntry a = (FsgIdEntry) o;
            if (a.graphIdSequence.size() > this.graphIdSequence.size()) {
                return -1;
            } else if (a.graphIdSequence.size() < this.graphIdSequence.size()) {
                return 1;
            } else if (graphIdSequence.size() == 1) {
                int as = a.graphIdSequence.iterator().next();
                int ts = this.graphIdSequence.iterator().next();
                if (ts < as) {
                    return -1;
                } else if (ts > as) {
                    return +1;
                } else {
                    return 0;
                }
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    @Override
    public String toString() {
        Vector<Integer> idl = getGraphId();
        if (idl != null && idl.size() > 0) {
            StringBuffer ret = new StringBuffer(idl.firstElement() + "");
            int size = idl.size();
            for (int i = 1; i < size; i++) {
                ret.append("-" + idl.elementAt(i));
            }
            return ret.toString();
        } else {
            return "";
        }
    }

    /*
    public static HashSet<FsgIdEntry> intersect(HashSet<FsgIdEntry> set1,HashSet<FsgIdEntry> set2){
    HashSet<FsgIdEntry> result = new HashSet<FsgIdEntry>();
    Iterator<FsgIdEntry> set1i = set1.iterator();
    FsgIdEntry[] set2a = set2.toArray(new FsgIdEntry[1]);
    while(set1i.hasNext()){
    FsgIdEntry set1in = set1i.next();
    Integer[] set1inids=set1in.graphIdSequence.toArray(new Integer[1]);
    for(int i=0;i<set2a.length;i++){
    boolean overlap=false;
    for(int j=0;j<set1inids.length;j++){
    if(set2a[i].graphIdSequence.contains(set1inids[j])){
    overlap=true;
    break;
    }
    }
    if(overlap){
    FsgIdEntry newentry = new FsgIdEntry(set1in.graphIdSequence);
    newentry.graphIdSequence.addAll(set2a[i].graphIdSequence);
    result.add(newentry);
    }
    }
    }
    return result;
    }*/
    public void addGraphIds(FsgIdEntry newentry) {
        graphIdSequence.addAll(newentry.graphIdSequence);
    }

    public static FsgIdEntry combine(FsgIdEntry e1, FsgIdEntry e2) {
        FsgIdEntry res = new FsgIdEntry(e1.graphIdSequence);
        res.graphIdSequence.addAll(e2.graphIdSequence);
        return res;
    }
}
